﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Streambolics
{
    /// <summary>
    ///     A computing module that executes an action when triggered.
    /// </summary>

    public abstract class TriggeredComputingModule : PolledComputingModule
    {
        private DateTime _ActionTime;
        private DateTime _ActionLastTime;

        private TimeSpan _ActionDelay = 10.Seconds ();
        private TimeSpan _MaxActionDelay = 1.Minutes ();

        private bool _Important = false;

        protected abstract void ExecuteTriggeredAction ();

        /// <summary>
        ///     Trigger the action.
        /// </summary>

        public void Trigger ()
        {
            if (_ActionLastTime == DateTime.MaxValue)
            {
                _ActionLastTime = _MaxActionDelay.FromNow ();
            }
            _ActionTime = _ActionDelay.FromNow ();
            if (_ActionTime > _ActionLastTime)
            {
                _ActionTime = _ActionLastTime;
            }

            if (!IsRunning && _Important)
            {
                ClearSchedule ();
                try
                {
                    ExecuteTriggeredAction ();
                }
                catch (Exception e)
                {
                    DeclareFailed (e);
                }
            }
        }

        private void ClearSchedule ()
        {
            _ActionTime = DateTime.MaxValue;
            _ActionLastTime = DateTime.MaxValue;
        }

        protected override void DoPoll ()
        {
            if (DateTime.Now >= _ActionTime)
            {
                ClearSchedule ();
                ExecuteTriggeredAction ();
            }
        }

        protected override void DoStart ()
        {
            ClearSchedule ();
            DeclareStarted ();
        }

        protected override void DoStop ()
        {
            if (_ActionTime != DateTime.MaxValue)
            {
                ExecuteTriggeredAction ();
            }
            ClearSchedule ();
            DeclareStopped ();
        }
    }
}
